Heap
๊ด๋ จ ์ ๋ฆฌ. Heap
์ ์ฃผ๋ก Array๋ก ๊ตฌํํ๋ฉฐ, ๊ฐ์ฅ ํฐ ์์ดํ
์ด๋ ๊ฐ์ฅ ์์ ์์ดํ
์ O(1)
์ ์๊ฐ๋ณต์ก๋๋ก ๊ตฌํ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ์
๋ฐ์ดํธ ํ๋๋ฐ์ O(log n)
์ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค. set
์ฒ๋ผ k
๊ฐ์ ๊ฐ์ง๋ ์์ดํ
์ ์ฐพ๊ฑฐ๋ ํ ์๋ ์์ง๋ง, ๊ตฌ์กฐ๊ฐ ๋น๊ต์ ๊ฐ๋จํ๋ ์ตํ๋๋ฉด ์ข๋ค. ๊ทธ๋ฆฌ๊ณ , ์ต์ ํ๊ฐ ๋งค์ฐ ๊ฐ๋ฅํ ๋
์์ด๋ค. ์๋ ์ฝ๋๊ฐ ๋๋ฆ์ ๋นํธ์ฐ์ฐ์ ์ฌ์ฉํ ์ต์ ์ด๋ ๊ผญ ์ตํ๋๋๋ก ํ์.
๋ง์ฝ 1-indexed
Heap
์ ๊ตฌํํ๋ค๊ณ ํ๋ฉด, ์๋์ฒ๋ผ ๋ถ๋ชจ, ์์๊ฐ์ ๊ด๊ณ๋ฅผ ์ ์ํ ์ ์๋ค. (๋ฉ๋ชจ๋ฆฌ๋ 1๋งํผ ๋ญ๋น๋์ง๋ง, Index ๊ณ์ฐ์์ ๋ง์ด ํธ๋ฆฌํ๋ค)
idx >> 1
idx << 1
(idx << 1) | 1
์ ๋ฐฉ์์ผ๋ก ๊ฐ๋จํ๊ฒ Array๋ฅผ Tree๋ก ์ฌ์ฉํ ์ ์๋ค.
๋ง์ฝ ํ์ฌ์ Heap
์ ํฌ๊ธฐ๊ฐ sz
๋ผ๊ณ ํ์. ๊ทธ๋ ๋ค๋ฉด, ๋ค์์ ๋ค์ด๊ฐ ์์์ ์์น๋ sz + 1
์ด๋ค. (์ด๊ธฐ ์กฐ๊ฑด์ ์๊ฐํ์)
์ด๋ ๊ฒ ์์๋ฅผ ๋์ถฉ ์ฝ์
ํ ์ดํ์, ์ด๋ฅผ ๊ณ์ ์์ level์ ์์ดํ
๊ณผ ๋น๊ตํ์ฌ, swapํ๋ฉด ๋๋ค. ์๋๋ MinHeap
์์์ ์์์ด๋ค.
T d[SZ + 1];int sz;void push(T v) {int p = ++sz;for(; p > 1; p >>= 1) {if (d[p>>1] <= v) break; // ์ด๋ฏธ ์กฐ๊ฑด์ ๋ง์กฑํ๊ณ ์์ผ๋ฉด breakd[p] = d[p>>1];}d[p] = v;}
๋์ถฉ Insertion Sort
์ ๋ชจ์ต์ด ๋น์ทํ๋, ์ ์๋๋ฉด ์ ๋ ฌ ์ฐ์ต์ ๋ค์ ํ๊ณ ์ค์.
์ด๊ฒ ์ข ์ด๋ ต๋ค. ์ฐ์ , 1๋ฒ index
์ ๋ฐ์ดํฐ๊ฐ ๋น ์ ธ๋๊ฐ๋ค. ๊ทธ๋ฆฌ๊ณ ๋์ swap์ด ์์๋ ํ
๋ฐ, ์ต์ข
์ ์ผ๋ก ์ฝ์
ํ ๋
์์ sz
์์น์ ์๋ ์์ดํ
์ด ๋ ๊ฒ์ด๋ค. ์ด๊ฒ์ ์บ์ํด์ ๊ฐ์ง๊ณ ์๋๋ค. ๊ทธ๋ฆฌ๊ณ , ์ ์ฌ์ ์ผ๋ก ์ฝ์
๋ ์์น๋ฅผ ์ฐพ์๊ฐ๋ค. ๋งจ ์ฒ์์๋ c = 2
์์ ์์ํ ๊ฒ์ด๋ค. ์ข์ธก ์์์ผ๋ก swap ํ๋ค๊ณ ์๊ฐํ ์ดํ, ์ฐ์ธก ์์์ ์กฐ๊ฑด์ด ๋ ์ข์ผ๋ฉด ์ฐ์ธก ์์ํ๊ณ swap ํ๋ค. ์ด๊ฒ์ ๋ฐ๋ณตํ๊ณ , ์ ์ ํ ์ฝ์
์์น๊ฐ ์ฐพ์์ก์ผ๋ฉด, ๋ฃ๊ณ ๋๋ธ๋ค.
T d[SZ + 1];int sz;T pop() {T r = d[1];T val = d[sz--];int c = 2; // ์ผ์ชฝ ์์๋ถํฐ ๊ฒ์ฌfor(; c <= sz && d[c |= (c < sz && d[c] >= d[c|1])] < val; c <<= 1) {d[c>>1] = d[c];}d[c>>1] = val;return r;}
heap
์ ์ฝ์
๋ ์์ ์ Index
๋ฅผ ์ ์ฅํด์ฃผ๋ฉด, ํน์ ์์์ ๊ฐ์ ์ฐพ์ ์ ์๊ณ , ๊ทธ Index
์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค. ๋ณ๊ฒฝ ํ์๋ swim
๊ณผ sink
๋ฅผ ์์ ๊ด๊ณ์์ด 1๋ฒ์ฉ ํด์ฃผ๋ฉด ๋ค์ heap
์ ๊ตฌ์กฐ๊ฐ ์ ์ง๋๋ค. ์ด๋ฅผ ํ์ฉํ ์ ์ฒด heap
์ฝ๋์ ์ํ์ ์๋์ ๊ฐ๋ค.
struct Heap {T data[SZ + 1];int posToID[SZ + 1]; // ์์น p์ ์๋ ๋ ์์ idint idToPos[ID_MAX]; // id๊ฐ ์ด๋ ์์น p์ ์๋์งint sz;void init() { sz = 0; }void push(int idx, T v) {int p = ++sz;for(; p > 1; p >>= 1) {if (d[p>>1] <= v) break; // ์ด๋ฏธ ์กฐ๊ฑด์ ๋ง์กฑํ๊ณ ์์ผ๋ฉด breakd[p] = d[p>>1];idToPos[id[p]] = idToPos[id[p>>1]];posToID[p] = posToID[p>>1];}d[p] = v;posToID[p] = idx;idToPos[idx] = p;}T pop() {T r = d[1];int idx = posToID[sz];T val = d[sz--];int c = 2; // ์ผ์ชฝ ์์๋ถํฐ ๊ฒ์ฌfor(; c <= sz && d[c |= (c < sz && d[c] >= d[c|1])] < val; c <<= 1) {d[c>>1] = d[c];idToPos[id[c>>1]] = idToPos[id[c]];posToID[c>>1] = posToID[c];}d[c>>1] = val;posToID[c>>1] = idx;idToPos[idx] = c>>1;return r;}T getData(int idx) {return d[idToPos[idx]];}void updateData(int idx, T v) {int spos = idToPos[idx];d[spos] = v;// ์๋ก ๊ฐฑ์ (swim)int p = spos;for(; p > 1; p >>= 1) {if (d[p>>1] <= v) break; // ์ด๋ฏธ ์กฐ๊ฑด์ ๋ง์กฑํ๊ณ ์์ผ๋ฉด breakd[p] = d[p>>1];idToPos[id[p]] = idToPos[id[p>>1]];posToID[p] = posToID[p>>1];}d[p] = v;posToID[p] = idx;idToPos[idx] = p;// ์๋๋ก ๊ฐฑ์ (sink)int c = spos << 1; // ์ผ์ชฝ ์์๋ถํฐ ๊ฒ์ฌfor(; c <= sz && d[c |= (c < sz && d[c] >= d[c|1])] < val; c <<= 1) {d[c>>1] = d[c];idToPos[id[c>>1]] = idToPos[id[c]];posToID[c>>1] = posToID[c];}d[c>>1] = val;posToID[c>>1] = idx;idToPos[idx] = c>>1;}};
์์์๋ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์๊ฐํ๋ฉฐ ๊ตฌํํ heap
์ ๋ณด์๋ค๋ฉด, ์ข ๋ ์ฝ๋ ์ง๊ด์ ์ธ heap
์ ๊ตฌํ์ ์๋์ ๊ฐ๋ค.
#define parent(id) ((id) >> 1)#define left(id) ((id) << 1)#define right(id) (((id) << 1) | 1)struct Heap {int d[SZ + 1];int sz;void init() { sz = 0; }void swap(int aIdx, int bIdx) {d[aIdx] ^= d[bIdx] ^= d[aIdx] ^= d[bIdx];}void swim(int idx) {int pidx = parent(idx);if (pidx <= 0) return;if (d[idx] >= d[pidx]) return;swap(idx, pidx);swim(pidx);}void sink(int idx) {int cidx = left(idx);if (cidx > sz) return;if ((cidx|1) <= sz && d[cidx] > d[cidx|1]) cidx |= 1;if (d[idx] <= d[cidx]) return;swap(idx, cidx);sink(cidx);}void push(int v) {d[++sz] = v;swim(sz - 1);}int pop() {int r = d[1];d[1] = d[sz--];sink(1);return r;}};
swim
์ ์์ชฝ์ผ๋ก ์ฌ๋ผ๊ฐ๋ ๋ชจ์ต์ด๊ณ , sink
๋ ๊ฐ๋ผ์๋ ๋ชจ์ต์์ ์ด๋ฆ์ด ๋ถ์๋ค. ๋ค๋ง ์ฌ๊ท๋ก ๊ตฌํํ๊ธฐ ๋๋ฌธ์ O2
์ ๊ฐ์ ์ปดํ์ผ ์ต์
์ด ๋ถ์ง ์๋๋ค๋ฉด ์ผ๋ฐ ๋ฃจํ๋ก ๊ตฌํํ ๊ฒ๋ณด๋ค ํ์คํ ๋๋ฆฌ๋ค.